package middle.code;

import lombok.extern.slf4j.Slf4j;

/**
 * 1.题目描述
 * 给定一个函数f1可以实现1-5范围内的等概率，通过这个函数而不使用别的函数实现1-7内等概率返回
 * <p>
 * 2.题目分析 （以下套路可以解决任何随机数范围）
 * 第一步（0～1 等概率生成器）：f1实现1-5等概率返回，我们可以把它改造成0，1发生器，1-2返回0，4-5返回1，如果3，就返回重新生成；f2
 * 第二步（0～2^n 等概率生成器）：0，1发生器随机生成0，1。我们让随机生成3次，就可以得到000-111等概率，即0-7等概率；f3
 * 第三步（0～N 等概率生成器）：我们要得到1-7，即0-6等概率，将f3的7返回，得到0-6等概率（f3）。
 * 第四步（Z~Z+N 等概率生成器）：+1得到g(x)
 */
@Slf4j
public class Code01_Random {
    public static int f1() {
        return (int) (Math.random() * 5) + 1;
    }

    public static int f2() {
        int randomNum = -1;
        do {
            randomNum = f1();
        } while (randomNum == 3);

        return randomNum < 3 ? 0 : 1;
    }

    public static int f3() {
        int random = -1;
        do {
            random = (f2() << 2) + (f2() << 1) + f2(); // 注意允许顺序
        } while (random == 7);
        return random;
    }

    public static int f4() {
        return f3() + 1;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 200; i++) {
            log.info("random 1~7, number: {}", f4());
        }
    }
}
